﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Build;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;
using UnityEngine.AddressableAssets;
using File = System.IO.File;

namespace SCore.Editor.BuildPackage.Addressable
{
    public partial class BuildAddressable
    {
        /// <summary>
        /// Addressable 全局设置
        /// </summary>
        private static AddressableAssetSettings Settings => AddressableAssetSettingsDefaultObject.Settings;

        /// <summary>
        /// 获取remoteBuild 逻辑
        /// </summary>
        /// <returns></returns>
        public static string GetAASRemoteBuildDir()
        {
            var profileSettings = Settings.profileSettings;
            var propName =
                profileSettings.GetValueByName(Settings.activeProfileId, AddressableAssetSettings.kRemoteBuildPath);
            var remoteBuildDir = profileSettings.EvaluateString(Settings.activeProfileId, propName);
            return remoteBuildDir;
        }

        /// <summary>
        /// 首包
        /// </summary>
        [MenuItem("SCore/Build/Addressable/Build All Content")]
        public static void BuildAddressableContent()
        {
            AddressableAssetSettings.BuildPlayerContent(out var result);
            Addressable.BuildAddressable.BuildAddressableContentFinish(result);
        }

        // [MenuItem("Gmx/test_LoadContentBin")]
        public static void TestLoadContentBin()
        {
            var path = ContentUpdateScript.GetContentStateDataPath(false);
            path += "_last_hope";
            var cacheData = ContentUpdateScript.LoadContentState(path);
            var j = JsonUtility.ToJson(cacheData, true);
            // Write to file -- 会丢失data对象，逆向不全...
            // File.WriteAllText(path + ".json", j);
            // using (StreamWriter writer =
            //        new StreamWriter("/Users/Sprite/work/xnext/doc/lost0218/content_ios.json", false))
            // {
            //     writer.WriteLine(j); // 将文本写入文件
            // }
            //
            //
            // Debug.Log("[BuildPipeline]:LoadContentBin = \n" + j);
        }

        // [MenuItem("Gmx/test_SaveContentBin")]
        public static void TestSaveContentBin()
        {
            var path = ContentUpdateScript.GetContentStateDataPath(false);
            path += "_recovery";

            var jsonFileName = "/Users/Sprite/work/xnext/doc/lost0218/content_recovery.json";
            using (StreamReader reader = new StreamReader(jsonFileName))
            {
                var j = reader.ReadToEnd();
                var cacheData = JsonUtility.FromJson<AddressablesContentState>(j);

                var formatter = new BinaryFormatter();
                if (File.Exists(path))
                    File.Delete(path);
                var dir = Path.GetDirectoryName(path);
                if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir))
                    Directory.CreateDirectory(dir);
                var stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write);
                formatter.Serialize(stream, cacheData);
                stream.Flush();
                stream.Close();
                stream.Dispose();
            }
        }

        /// <summary>
        /// 更新包
        /// </summary>
        [MenuItem("SCore/Build/Addressable/BuildUpdate")]
        public static void BuildAddressableUpdate()
        {
            if (Application.isPlaying)
            {
                return;
            }

            var path = ContentUpdateScript.GetContentStateDataPath(false);
            var result = ContentUpdateScript.BuildContentUpdate(Settings, path);
            Addressable.BuildAddressable.BuildAddressableContentFinish(result);
            Debug.Log("[BuildPipeline]:BuildAddressableUpdate path = " +
                      Settings.RemoteCatalogBuildPath.GetValue(Settings));
        }

        /// <summary>
        /// 全量更新使用
        /// </summary>
        [MenuItem("SCore/Build/Addressable/Prepare Update Content")]
        public static void CheckForUpdateContent()
        {
            //与上次打包做资源对比
            var buildPath = ContentUpdateScript.GetContentStateDataPath(false);
            var m_Settings = AddressableAssetSettingsDefaultObject.Settings;
            var entrys =
                ContentUpdateScript.GatherModifiedEntries(
                    m_Settings, buildPath);
            if (entrys.Count == 0) return;
            var sbuider = new StringBuilder();
            sbuider.AppendLine("Need Update Assets:");
            foreach (var _ in entrys) sbuider.AppendLine(_.address);
            Debug.Log("[BuildPipeline]:" + sbuider.ToString());
            //将被修改过的资源单独分组
            var groupName = string.Format("UpdateGroup_{0}", DateTime.Now.ToString("yyyyMMdd"));
            ContentUpdateScript.CreateContentUpdateGroup(m_Settings, entrys, groupName);
        }

        [MenuItem("SCore/Build/Addressable/Test")]
        public static void Test()
        {
            ("[BuildPackage]:BuildPath = " + Addressables.BuildPath).Log();
            ("[BuildPackage]:PlayerBuildDataPath = " + Addressables.PlayerBuildDataPath).Log();
            ("[BuildPackage]:RemoteCatalogBuildPath = " +
             AddressableAssetSettingsDefaultObject.Settings.RemoteCatalogBuildPath.GetValue(
                 AddressableAssetSettingsDefaultObject.Settings)).Log();
            ("[BuildPackage]:BuildUpdate Bin Path = " + ContentUpdateScript.GetContentStateDataPath(false)).Log();
        }

        [MenuItem("SCore/Build/Addressable/ChangeProfile")]
        public static void SetProfile(string profileName = "dev")
        {
            var dev = Settings.profileSettings.GetProfileId(profileName);
            Settings.activeProfileId = dev;
        }
    }
}